﻿/*! @file
********************************************************************************
<PRE>
文 件 名    : CSProjFile.cs
说    明    : 转换 CSPROJ项目文件
作    者    : 汪泽然
--------------------------------------------------------------------------------
备    注    : VisualStudio2005.CSharp
--------------------------------------------------------------------------------
修改记录: 
 * 日    期    版  本    修改人    修改内容 
 * 2009-7-9    0.1.0     汪泽然    完成基本转换功能
 * 2009-7-2    0.1.1     汪泽然    修复当Project节点不存在ToolsVersion属性时，会删除整个Project节点的Bug
</PRE>
********************************************************************************
* 版权所有(c) 2008 ~ 2009, 汪泽然, 保留所有权利
*******************************************************************************/
using System;
using System.IO;
using System.Xml;
using System.Text;
using System.Xml.XPath;
using Wangzeran.Transform.Core.ITransform;
using Wangzeran.Transform.Core.TransformException;
using System.Collections.Generic;
using Wangzeran.Transform.Core.Support;

namespace Wangzeran.Transform.PlugIn.VisualStudio2005.CSharp
{
    /// <summary>
    /// 转换 CSPROJ项目文件
    /// </summary>
    public class CSProjFile : BaseProjFile
    {

        #region Common Properties

        /// <summary>
        /// 当前项目文件版本
        /// </summary>
        protected override string CURRENT_VERSION
        {
            get
            {
                return "8.0.50727";
            }
        }

        #endregion


        #region BaseProjFile成员

        /// <summary>
        /// 转换项目文件
        /// </summary>
        /// <param name="filePath">项目文件完整路径</param>
        /// <returns>True：转换成功 False：转换失败</returns>
        /// <exception cref="TransformFailureException">转换失败的异常</exception>
        public override bool Transform(string filePath)
        {
            XmlDocument doc = null;
            try
            {
                if (!File.Exists(filePath))
                {
                    return false;
                }
                doc = new XmlDocument();
                doc.Load(filePath);

                //XmlNode rootNode = doc.SelectSingleNode("/ms:Project");
                //if (rootNode == null)
                //{
                //    throw new TransformFailureException("非法的项目文件");
                //}




                string nodeName;
                using (XmlTextWriter tr = new XmlTextWriter(filePath, Encoding.Unicode))
                {
                    try
                    {
                        XPathNavigator nav = doc.CreateNavigator();
                        XmlNamespaceManager manager = new XmlNamespaceManager(nav.NameTable);
                        manager.AddNamespace("ms", COMMON_XMLNAMESPACE);

                        // 移除XML声明
                        if (doc.ChildNodes[0].NodeType == XmlNodeType.XmlDeclaration)
                        {
                            doc.RemoveChild(doc.ChildNodes[0]);
                        }

                        // 移除Project的ToolsVersion属性
                        XPathNodeIterator iter = nav.Select("/ms:Project", manager);
                        if(iter.MoveNext())
                        {
                            if (iter.Current.MoveToAttribute("ToolsVersion", ""))
                            {
                                iter.Current.DeleteSelf();
                            }
                        }

                        iter = nav.Select("/ms:Project", manager);
                        while (iter.MoveNext())
                        {
                            XPathNodeIterator parIter = iter.Current.SelectDescendants(
                                XPathNodeType.Element, false);
                            while (parIter.MoveNext())
                            {
                                if (parIter.Current.Name == "PropertyGroup")
                                {
                                    XPathNodeIterator newIter = parIter.Current.SelectDescendants(
                                        XPathNodeType.Element, false);
                                    while (newIter.MoveNext())
                                    {
                                        nodeName = newIter.Current.Name;
                                        if (nodeName == "ProductVersion")
                                        {
                                            // 将 Project/PropertyGroup/ProductVersion设置为当前版本
                                            newIter.Current.SetValue(CURRENT_VERSION);
                                            continue;
                                        }
                                        if (nodeName == "FileUpgradeFlags"
                                            || nodeName == "UpgradeBackupLocation"
                                            || nodeName == "OldToolsVersion"
                                            || nodeName == "TargetFrameworkVersion"
                                            || nodeName == "FileAlignment")
                                        {
                                            // 删除 Project/PropertyGroup/FileUpgradeFlags
                                            // 删除 Project/PropertyGroup/UpgradeBackupLocation
                                            // 删除 Project/PropertyGroup/OldToolsVersion
                                            // 删除 Project/PropertyGroup/TargetFrameworkVersion
                                            // 删除 Project/PropertyGroup/FileAlignment
                                            newIter.Current.DeleteSelf();
                                            continue;
                                        }
                                    }
                                }
                                else if (parIter.Current.Name == "ItemGroup")
                                {
                                    XPathNodeIterator newIter = parIter.Current.SelectDescendants(
                                        XPathNodeType.Element, false);
                                    while (newIter.MoveNext())
                                    {
                                        if (newIter.Current.Name == "Reference")
                                        {
                                            nodeName = newIter.Current.GetAttribute("Include", 
                                                manager.DefaultNamespace);
                                            if (nodeName == "System.Core"
                                                || nodeName == "System.Xml.Linq"
                                                || nodeName == "System.Data.DataSetExtensions")
                                            {
                                                // Project/ItemGroup/Reference
                                                // 删除项目引用 System.Core
                                                // 删除项目引用 System.Xml.Linq
                                                // 删除项目引用 System.Data.DataSetExtensions
                                                newIter.Current.DeleteSelf();
                                                continue;
                                            }
                                        }
                                    }
                                }
                                else if (parIter.Current.Name == "Import")
                                {
                                    // 更改Project/Import节点的Project属性值
                                    XPathNodeIterator newIter = parIter.Current.SelectDescendants(
                                        XPathNodeType.Attribute, false);
                                    newIter.Current.MoveToAttribute("Project", 
                                        manager.DefaultNamespace);
                                    newIter.Current.SetValue("$(MSBuildBinPath)\\Microsoft.CSharp.targets");
                                }
                            }
                        }
                    }
                    finally
                    {
                        tr.Formatting = Formatting.Indented;
                        doc.WriteContentTo(tr);
                    }
                }
                return true;
            }
            catch (Exception ex)
            {
                throw new TransformFailureException(filePath, ex.Message);
            }
        } 

        #endregion


        /// <summary>
        /// 初始化要获取的附属文件实现类集合
        /// </summary>
        /// <param name="lstInterface"></param>
        protected override void InitChildFileInterfaces(IList<IChildFile> lstInterface)
        {
            lstInterface.Add(new SubFiles.CSFile());
            lstInterface.Add(new SubFiles.WebConfigFile());
        }
    }
}
